package systemMapperImpl

import (
	"baize/app/business/system/systemModels"
	"baize/app/constant/sessionStatus"
	"baize/app/datasource"
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"log"
)

type SysRoleMapper struct {
	collection func(ctx context.Context) *mongo.Collection
}

func NewNewSysRoleMapper(c *mongo.Client) *SysRoleMapper {
	return &SysRoleMapper{
		collection: func(ctx context.Context) *mongo.Collection {
			s := ctx.Value(sessionStatus.CompanyIdAbbreviate).(string)
			return c.Database(s).Collection(datasource.Collection["role"])
		},
	}
}

func (rm *SysRoleMapper) SelectRoleList(ctx context.Context, role *systemModels.SysRoleDQL) (list []*systemModels.SysRoleVo, total *int64) {
	//whereSql := " where r.del_flag = '0'"
	//if role.RoleName != "" {
	//	whereSql += " AND r.role_name like concat('%', :role_name, '%')"
	//}
	//if role.Status != "" {
	//	whereSql += " AND r.status = :status"
	//}
	//if role.RoleKey != "" {
	//	whereSql += " AND r.role_key like concat('%', :role_key, '%')"
	//}
	//if role.BeginTime != "" {
	//	whereSql += " and date_format(r.create_time,'%y%m%d') >= date_format(:begin_time,'%y%m%d')"
	//}
	//if role.EndTime != "" {
	//	whereSql += " and date_format(r.create_time,'%y%m%d') <= date_format(:end_time,'%y%m%d')"
	//}
	//list = make([]*systemModels.SysRoleVo, 0, 16)
	//total = new(int64)
	//err := db.NamedSelectPageContext(ctx, &list, total, rd.selectSql+whereSql, role, role.ToPage())
	//if err != nil {
	//	panic(err)
	//}
	return
}
func (rm *SysRoleMapper) SelectRoleAll(ctx context.Context, role *systemModels.SysRoleDQL) (list []*systemModels.SysRoleVo) {
	//whereSql := " where r.del_flag = '0'"
	//if role.RoleName != "" {
	//	whereSql += " AND r.role_name like concat('%', :role_name, '%')"
	//}
	//if role.Status != "" {
	//	whereSql += " AND r.status = :status"
	//}
	//if role.RoleKey != "" {
	//	whereSql += " AND r.role_key like concat('%', :roleKey, '%')"
	//}
	//if role.BeginTime != "" {
	//	whereSql += " and date_format(r.create_time,'%y%m%d') >= date_format(:begin_time,'%y%m%d')"
	//}
	//if role.EndTime != "" {
	//	whereSql += " and date_format(r.create_time,'%y%m%d') <= date_format(:end_time,'%y%m%d')"
	//}
	//if role.CreateBy != 0 {
	//	whereSql += " and r.create_by = :create_by"
	//}
	//list = make([]*systemModels.SysRoleVo, 0)
	//err := db.NamedSelectContext(ctx, &list, rd.selectSql+whereSql, role)
	//if err != nil {
	//	panic(err)
	//}
	return
}
func (rm *SysRoleMapper) SelectRoleById(ctx context.Context, roleId int64) (role *systemModels.SysRoleVo) {
	//whereSql := ` where r.role_id = ?`
	//role = new(systemModels.SysRoleVo)
	//err := db.GetContext(ctx, role, rd.selectSql+whereSql, roleId)
	//if err != nil && !errors.Is(sql.ErrNoRows, err) {
	//	panic(err)
	//}
	return
}

func (rm *SysRoleMapper) SelectRoleListByUserId(ctx context.Context, userId int64) (list []int64) {
	//sqlStr := `select r.role_id
	//    from sys_role r
	//        left join sys_user_role ur on ur.role_id = r.role_id
	//        left join sys_user u on u.user_id = ur.user_id
	//	where u.user_id = ?`
	//list = make([]int64, 0, 1)
	//err := db.SelectContext(ctx, &list, sqlStr, userId)
	//if err != nil && !errors.Is(sql.ErrNoRows, err) {
	//	panic(err)
	//}
	return
}

func (rm *SysRoleMapper) InsertRole(ctx context.Context, sysRole *systemModels.SysRoleDML) {
	//insertSQL := `insert into sys_role(role_id,role_name,role_key,role_sort,status,remark,create_by,create_time,update_by,update_time )
	//				values(:role_id,:role_name,:role_key,:role_sort,:status,:remark,:create_by,now(),:update_by,now())`
	//_, err := db.NamedExecContext(ctx, insertSQL, sysRole)
	//if err != nil {
	//	panic(err)
	//}
	return
}

func (rm *SysRoleMapper) UpdateRole(ctx context.Context, sysRole *systemModels.SysRoleDML) {
	//updateSQL := `update sys_role set update_time = now() , update_by = :update_by`
	//
	//if sysRole.RoleName != "" {
	//	updateSQL += ",role_name = :role_name"
	//}
	//if sysRole.RoleKey != "" {
	//	updateSQL += ",role_key = :role_key"
	//}
	//if sysRole.RoleSort != -1 {
	//	updateSQL += ",role_sort = :role_sort"
	//}
	//
	//if sysRole.Remake != "" {
	//	updateSQL += ",remark = :remark"
	//}
	//if sysRole.Status != "" {
	//	updateSQL += ",status = :status"
	//}
	//updateSQL += " where role_id = :role_id"
	//_, err := db.NamedExecContext(ctx, updateSQL, sysRole)
	//if err != nil {
	//	panic(err)
	//}
	return
}

func (rm *SysRoleMapper) DeleteRoleByIds(ctx context.Context, ids []int64) {
	//query, i, err := sqly.In("update sys_role set del_flag = '2',role_name = concat(role_name,'(删除)')  where role_id in(?)", ids)
	//if err != nil {
	//	panic(err)
	//}
	//_, err = db.ExecContext(ctx, query, i...)
	//if err != nil {
	//	panic(err)
	//}
	return
}
func (rm *SysRoleMapper) CheckRoleNameUnique(ctx context.Context, roleName string) int64 {
	var roleId int64 = 0
	//err := db.GetContext(ctx, &roleId, "select role_id from sys_role where role_name = ?", roleName)
	//if err != nil && !errors.Is(sql.ErrNoRows, err) {
	//	panic(err)
	//}
	return roleId
}

func (rm *SysRoleMapper) CheckRoleKeyUnique(ctx context.Context, roleKey string) int64 {
	var roleId int64 = 0
	//err := db.GetContext(ctx, &roleId, "select role_id from sys_role where role_key = ?", roleKey)
	//if err != nil && !errors.Is(sql.ErrNoRows, err) {
	//	panic(err)
	//}
	return roleId
}
func (rm *SysRoleMapper) SelectAllocatedList(ctx context.Context, user *systemModels.SysRoleAndUserDQL) (list []*systemModels.SysUserVo, total *int64) {
	//selectStr := ` select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time`
	//
	//whereSql := ` from sys_user u
	//		 left join sys_dept d on u.dept_id = d.dept_id
	//		 left join sys_user_role ur on u.user_id = ur.user_id
	//		 left join sys_role r on r.role_id = ur.role_id where u.del_flag = '0' and r.role_id =:role_id`
	//if user.UserName != "" {
	//	whereSql += " AND u.user_name like concat('%', :user_name, '%')"
	//}
	//if user.Phonenumber != "" {
	//	whereSql += " AND u.phonenumber like concat('%', :phonenumber, '%')"
	//}
	//list = make([]*systemModels.SysUserVo, 0, 16)
	//total = new(int64)
	//err := db.NamedSelectPageContext(ctx, &list, total, selectStr+whereSql, user, user.ToPage())
	//if err != nil {
	//	panic(err)
	//}
	return

}

func (rm *SysRoleMapper) SelectUnallocatedList(ctx context.Context, user *systemModels.SysRoleAndUserDQL) (list []*systemModels.SysUserVo, total *int64) {
	//selectStr := ` select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time`
	//
	//whereSql := `  from sys_user u
	//		 left join sys_dept d on u.dept_id = d.dept_id
	//		 left join sys_user_role ur on u.user_id = ur.user_id
	//		 left join sys_role r on r.role_id = ur.role_id
	//    where u.del_flag = '0' and (r.role_id != :role_id or r.role_id IS NULL)
	//    and u.user_id not in (select u.user_id from sys_user u inner join sys_user_role ur on u.user_id = ur.user_id and ur.role_id = :role_id)`
	//if user.UserName != "" {
	//	whereSql += " AND u.user_name like concat('%', :user_name, '%')"
	//}
	//if user.Phonenumber != "" {
	//	whereSql += " AND u.phonenumber like concat('%', :phonenumber, '%')"
	//}
	//list = make([]*systemModels.SysUserVo, 0, 16)
	//total = new(int64)
	//err := db.NamedSelectPageContext(ctx, &list, total, selectStr+whereSql, user, user.ToPage())
	//if err != nil {
	//	panic(err)
	//}
	return

}
func (rm *SysRoleMapper) SelectMenuIdByRoleIds(ctx context.Context, roleIds []int64) (menuId []int64) {
	pipeline := mongo.Pipeline{
		{{"$unwind", "$tags"}},
		{{"$match", bson.M{"_id": bson.M{"$in": roleIds}}}},
		{{"$group", bson.M{
			"_id":           nil,
			"uniqueMenuIds": bson.M{"$addToSet": "$menu_ids"},
		}}},
		{{"$project", bson.M{"_id": 0, "uniqueMenuIds": 1}}},
	}

	// 执行聚合查询
	cursor, err := rm.collection(ctx).Aggregate(context.TODO(), pipeline)
	if err != nil {
		log.Fatal(err)
	}
	defer cursor.Close(ctx)

	// 定义结果结构
	type Result struct {
		UniqueMenuIds []int64 `bson:"uniqueMenuIds"`
	}
	var result Result

	// 获取单一结果文档
	if cursor.Next(ctx) {
		if err := cursor.Decode(&result); err != nil {
			panic(err)
		}
	}

	return result.UniqueMenuIds

	// 定义聚合管道
	//pipeline := mongo.Pipeline{
	//	// 1. 获取唯一标签
	//	{
	//		{"$unwind", "$perms_ids"},
	//	},
	//	{
	//		{"$group", bson.D{
	//			{"_id", nil},
	//			{"perms_id", bson.D{{"$addToSet", "$perms_ids"}}},
	//		}},
	//	},
	//	{
	//		{"$project", bson.D{{"_id", 0}, {"perms_id", 1}}},
	//	},
	//	// 2. 进行连表查询
	//	{
	//		{"$lookup", bson.D{
	//			{"from", "sys_menu"},
	//			{"localField", "perms_id"},
	//			{"foreignField", "_id"},
	//			//{"as", "details_info"},
	//		}},
	//	},
	//	{
	//		{"$unwind", "$details_info"},
	//	},
	//	{
	//		{"$project", bson.D{
	//			{"_id", 0},
	//			{"perm", 1},
	//		}},
	//	},
	//}
	//cursor, err := rd.collection(ctx).Aggregate(ctx, pipeline)
	//if err != nil {
	//	panic(err)
	//}
	//var result struct {
	//	Infos []string `bson:"infos"`
	//}
	//if cursor.Next(ctx) {
	//	if err := cursor.Decode(&result); err != nil {
	//		log.Fatal(err)
	//	}
	//}

	return
}
